package com.xiao.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiao.domain.ResponseResult;
import com.xiao.domain.constants.BlogCommentConstants;
import com.xiao.enums.AppHttpCodeEnum;
import com.xiao.exception.SystemException;
import com.xiao.mapper.BlogCommentMapper;
import com.xiao.domain.pojo.BlogComment;
import com.xiao.domain.pojo.BlogSysUser;
import com.xiao.domain.pojo.LoginUser;
import com.xiao.service.BlogCommentService;
import com.xiao.service.BlogSysUserService;
import com.xiao.utils.BeanCopyUtils;
import com.xiao.utils.SecurityUtils;
import com.xiao.domain.vo.CommentVo;
import com.xiao.domain.vo.PageVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;

@Service
public class BlogCommentServiceImpl extends ServiceImpl<BlogCommentMapper, BlogComment> implements BlogCommentService {

    @Autowired
    BlogSysUserService blogSysUserService;

    @Override
    public ResponseResult commentList(Integer commentType, Long articleId, Integer pageNum, Integer pageSize) {
        // 1. 创建查询条件
        LambdaQueryWrapper<BlogComment> wrapper = new LambdaQueryWrapper<>();

        if (commentType==BlogCommentConstants.COMMENT_TYPE_ARTICLE){ // 只有 评论类型 是文章的时候 才需要查询对应文章的评论
            wrapper.eq(BlogComment::getArticleId,articleId);// 查询对应的文章ID
        }

        wrapper.eq(BlogComment::getType,commentType);// 只查询目标类型的评论  文章/友链
        wrapper.eq(BlogComment::getRootId, BlogCommentConstants.ROOT_ARTICLE);// 先只查询根评论
        // 2. 分页
        Page<BlogComment> page = new Page(pageNum, pageSize);

        this.page(page,wrapper);

        // 3. 查询
        List<BlogComment> blogCommentList = page.getRecords();

        // 4.查询赋值 评论与被评论人昵称
        List<CommentVo> commentVoList = this.toCommentVoList(blogCommentList);

        // 5.追加 子评论
        // ------- 子评论 Start ---------
        // 设置 子评论
        for (CommentVo commentVo : commentVoList) {
            commentVo.setChildren(this.getChildren(commentVo.getId()));
        }
        // ------- 子评论 End ---------

        // 6.查询分页封装
        PageVo pageVo = new PageVo(commentVoList, page.getTotal());
        // 查询结果封装
        ResponseResult result = ResponseResult.okResult(pageVo);

        return result;
    }


    @Override
    public ResponseResult addComment(BlogComment comment) {
        // 如果没有登录不允许评论
        try {
            LoginUser loginUser = SecurityUtils.getLoginUser();
        } catch (Exception e) {
            throw new SystemException(AppHttpCodeEnum.NEED_LOGIN);// 需要登入后操作
        }

        // 当评论内容为空时,抛出提示
        if (!StringUtils.hasText(comment.getContent())){
            throw new SystemException(AppHttpCodeEnum.CONTENT_NOT_NULL); // 内容不允许为空
        }

        /**
         * insert 到数据库中;  但是直接赋值的话，我们的 更新、创建人及其对应的时间都是空的,需要需要自动填充*/
        super.save(comment);// 插入到 数据库中
        return ResponseResult.okResult();
    }

    // 封装成 VO 时，需要评论人和被评论人的 昵称，因此需要重新数据库里查询得到。
    private List<CommentVo> toCommentVoList(List<BlogComment> list){

        List<CommentVo> commentVoList = BeanCopyUtils.copyBeanList(list, CommentVo.class);
        // 遍历vo集合

        for (CommentVo commentVo : commentVoList) {
            // 获取并赋值评论人 昵称
            BlogSysUser blogSysUser = blogSysUserService.getById(commentVo.getCreateBy());
            String nickName = blogSysUser.getNickName();
            commentVo.setUsername(nickName);

            // 获取并赋值 被评论人 昵称
            if (commentVo.getToCommentUserId()!=BlogCommentConstants.ROOT_ARTICLE){ // 只有被评论人ID 不等于 -1 时才需要查询; 因为 -1 是表示直接评论文章
                BlogSysUser toBlogSysUser = blogSysUserService.getById(commentVo.getToCommentUserId());
                String toNickName = toBlogSysUser.getNickName();
                commentVo.setToCommentUserName(toNickName);
            }
            // 获取评论人头像
            BlogSysUser sysUser = blogSysUserService.getById(commentVo.getCreateBy());
            commentVo.setCreateByAvatar(sysUser.getAvatar());
        }

        return commentVoList;
    }


    /**
     * 根据 评论ID  where root_id = 评论ID 那么就是 评论ID 的子评论。
     * @param id 根评论ID
     * @return  返回根评论下子评论列表
     */
    private List<CommentVo> getChildren(Long id){

        // 1. 创建查询条件
        LambdaQueryWrapper<BlogComment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BlogComment::getRootId,id);//等于 根评论ID = 我们的 评论ID 即为 评论ID 的子评论
        wrapper.orderByAsc(BlogComment::getCreateTime);//按照评论时间升序
        // 2. 查询
        List<BlogComment> list = this.list(wrapper);

        // 3. 封装Vo (因为需要手动赋值，昵称,所以需要调用工具方法)
        List<CommentVo> commentVoList = this.toCommentVoList(list);

        return commentVoList;
    }


}